// https://sega.bsnk.me/allnet/amusement_ic/

#include "nfc_supported_card_plugin.h"
#include <flipper_application.h>
#include <nfc/protocols/felica/felica.h>
#include <bit_lib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define TAG "Amusement IC"

#define N_TABLES      8
#define ITERATION_ADD 5

static const uint8_t s_box[9][256] = {
    {0x24, 0x3c, 0xba, 0x36, 0xe3, 0x85, 0xa4, 0xd0, 0x93, 0x43, 0x73, 0xb9, 0x70, 0x6e, 0xc9,
     0xf1, 0x10, 0x0e, 0x9b, 0x2c, 0x97, 0xe7, 0x0b, 0x63, 0x6c, 0x29, 0x20, 0xfe, 0x86, 0xf3,
     0xe1, 0xf5, 0xf6, 0x9f, 0xb6, 0x16, 0x04, 0x7b, 0x8f, 0xab, 0xb1, 0x39, 0x2a, 0x1b, 0xeb,
     0x5c, 0xa8, 0xac, 0x38, 0x11, 0x12, 0x5f, 0x89, 0x3e, 0x7d, 0xca, 0xec, 0x53, 0xdb, 0x6d,
     0x1e, 0xd2, 0x81, 0x78, 0x96, 0x46, 0xff, 0xf9, 0x54, 0x1c, 0x28, 0x7a, 0x4f, 0xd3, 0xc0,
     0xdc, 0xc1, 0x6a, 0xf2, 0xbc, 0xcb, 0x57, 0xfd, 0x4a, 0xe4, 0xf0, 0xb2, 0xc7, 0x95, 0x40,
     0x62, 0x52, 0x41, 0xe2, 0xad, 0x49, 0xa6, 0xb5, 0x1f, 0x02, 0xc8, 0xda, 0x92, 0xe5, 0xb0,
     0xc5, 0x64, 0x76, 0x48, 0x21, 0xde, 0x0f, 0x45, 0x58, 0x4c, 0xdf, 0xa7, 0x84, 0xcf, 0xd5,
     0x15, 0x4e, 0x27, 0x80, 0x6b, 0x7f, 0xfc, 0x44, 0x71, 0x47, 0x22, 0xdd, 0x30, 0x0c, 0xa1,
     0x3b, 0xe0, 0x37, 0xa0, 0x35, 0x23, 0x90, 0x32, 0x74, 0xbf, 0x8d, 0xc2, 0xea, 0xd6, 0x50,
     0xbb, 0xd9, 0xc4, 0x83, 0xb4, 0x31, 0x68, 0x55, 0x8b, 0x5d, 0xf4, 0x72, 0x18, 0xb7, 0xef,
     0xf7, 0x98, 0x2d, 0x01, 0x03, 0x61, 0xcc, 0x0a, 0x8e, 0x13, 0x00, 0xe8, 0x14, 0xaf, 0x09,
     0x51, 0x75, 0xa5, 0x2f, 0x1d, 0x0d, 0x65, 0x8a, 0xcd, 0x66, 0x07, 0x3d, 0x05, 0xd8, 0x4b,
     0xe9, 0x9d, 0x99, 0x7c, 0x91, 0xd1, 0xb8, 0x19, 0xc3, 0x2b, 0x42, 0x69, 0x88, 0xc6, 0x79,
     0x17, 0x3a, 0x4d, 0x5b, 0xa2, 0x5a, 0xfb, 0x25, 0x3f, 0xbd, 0xf8, 0xed, 0xce, 0xe6, 0x87,
     0xa3, 0x26, 0xa9, 0x2e, 0xbe, 0x94, 0x08, 0x7e, 0x67, 0x60, 0x8c, 0x9c, 0x5e, 0x6f, 0xb3,
     0x9e, 0x06, 0xfa, 0x82, 0xae, 0xee, 0x59, 0x77, 0xd7, 0x1a, 0x9a, 0x34, 0xd4, 0x56, 0xaa,
     0x33},
    {0xf9, 0x81, 0x7c, 0x00, 0xb9, 0x30, 0x37, 0xd5, 0x90, 0x51, 0x6e, 0xf0, 0xb2, 0x06, 0xfb,
     0xcd, 0x39, 0x14, 0x5f, 0xf8, 0x1b, 0xc7, 0x4a, 0x82, 0x70, 0x8c, 0x92, 0x1d, 0xea, 0xc3,
     0x4e, 0xc8, 0x12, 0xe6, 0xb6, 0x10, 0xd3, 0x2f, 0x95, 0x84, 0x25, 0x42, 0xa5, 0x72, 0xe5,
     0x8f, 0x55, 0xef, 0x86, 0xa2, 0x53, 0xae, 0xed, 0x26, 0x20, 0x47, 0xde, 0x78, 0x68, 0x28,
     0xe4, 0x45, 0xcc, 0x35, 0xbc, 0x3e, 0xbb, 0x8e, 0xc0, 0xbe, 0x34, 0xaf, 0xa6, 0x09, 0x64,
     0x01, 0x7b, 0x44, 0xf5, 0xf3, 0xb1, 0x3f, 0xa4, 0xb3, 0x32, 0x80, 0xc9, 0x4f, 0x6f, 0x40,
     0xbf, 0x21, 0x4c, 0x74, 0xe1, 0x11, 0x5e, 0xeb, 0x3d, 0x71, 0x2e, 0x9d, 0x62, 0x75, 0xd4,
     0x16, 0x48, 0x77, 0x13, 0x67, 0xad, 0x6b, 0x5d, 0x07, 0x87, 0xf7, 0xa8, 0x9a, 0x59, 0x76,
     0x8b, 0x9b, 0x1e, 0xd8, 0xee, 0xaa, 0xe9, 0x99, 0x2d, 0xc5, 0x97, 0xf1, 0xa7, 0x83, 0xfc,
     0xca, 0xdc, 0xba, 0xb8, 0x4b, 0xe8, 0x89, 0x17, 0x05, 0x0b, 0xa0, 0x65, 0x23, 0xd1, 0xce,
     0x36, 0x03, 0xd7, 0xe0, 0xf2, 0x91, 0xdf, 0x0e, 0x9c, 0x2c, 0x0d, 0x66, 0xd6, 0x73, 0x58,
     0x5c, 0xb4, 0x0a, 0x4d, 0xc2, 0x3b, 0xd2, 0xb7, 0xe2, 0xac, 0x33, 0xdb, 0x60, 0x27, 0xbd,
     0x56, 0x43, 0x24, 0x04, 0x02, 0x8d, 0x7d, 0x7f, 0xf6, 0xb5, 0xf4, 0xfd, 0xdd, 0x5b, 0xec,
     0x79, 0xc4, 0x22, 0x1f, 0xa1, 0x88, 0x54, 0xe7, 0x19, 0x98, 0x94, 0x7e, 0x31, 0xa3, 0x29,
     0xe3, 0x5a, 0xcb, 0x6a, 0xb0, 0xcf, 0x6d, 0x93, 0x6c, 0x7a, 0x08, 0xa9, 0x3c, 0x1c, 0xd0,
     0x63, 0x50, 0xc6, 0x85, 0x38, 0xc1, 0x41, 0x49, 0xab, 0x61, 0x52, 0x2a, 0x9f, 0xd9, 0x18,
     0x1a, 0x57, 0x46, 0x2b, 0x69, 0xda, 0xfa, 0xff, 0x0f, 0x15, 0x96, 0x3a, 0x8a, 0xfe, 0x9e,
     0x0c},
    {0x11, 0xa2, 0x9a, 0xc3, 0x94, 0xa0, 0x51, 0x01, 0x5b, 0xf7, 0xd1, 0x30, 0xee, 0x1f, 0x06,
     0xd5, 0x77, 0x67, 0xd3, 0xc1, 0x6e, 0xe7, 0x6a, 0x1a, 0xa4, 0x8e, 0x9f, 0x65, 0x66, 0xd6,
     0x0c, 0x2d, 0xc6, 0xe4, 0x69, 0xb7, 0x56, 0x5a, 0x57, 0x60, 0xfc, 0x79, 0x1e, 0xe1, 0x16,
     0x52, 0xf0, 0x07, 0xd0, 0xcd, 0xca, 0x78, 0xc9, 0x8b, 0xb3, 0x88, 0x27, 0xf6, 0xe0, 0xc0,
     0x84, 0xcf, 0x2f, 0xa3, 0x04, 0x00, 0x80, 0x40, 0xa7, 0xfa, 0x75, 0x9d, 0x4b, 0x89, 0x46,
     0x22, 0x28, 0x37, 0x34, 0x13, 0xff, 0x20, 0xb4, 0xda, 0x08, 0x26, 0x6c, 0x8f, 0xf2, 0x5d,
     0x7b, 0x73, 0x5c, 0x4c, 0x90, 0x71, 0x41, 0x8a, 0x9e, 0xbb, 0x12, 0xe8, 0x55, 0x6d, 0x2a,
     0x25, 0x4a, 0xaf, 0xbd, 0x95, 0x19, 0xa5, 0x31, 0xba, 0xad, 0xd9, 0xc5, 0xa6, 0x6b, 0x83,
     0xc4, 0xb6, 0xa9, 0xcc, 0xf9, 0xa1, 0xb1, 0x7a, 0xdc, 0xc7, 0xdb, 0x2e, 0x7e, 0x7f, 0x8d,
     0x4e, 0x62, 0x0f, 0x03, 0x39, 0xfd, 0xb8, 0xd4, 0x18, 0xc2, 0xec, 0x61, 0x02, 0x53, 0x1c,
     0x3b, 0x7d, 0xbc, 0x1d, 0x59, 0xf5, 0x8c, 0x98, 0xf1, 0x6f, 0x93, 0x85, 0xf8, 0x2c, 0x74,
     0xd8, 0x5e, 0x4d, 0x97, 0xab, 0x87, 0x82, 0x0a, 0x21, 0x42, 0x5f, 0x0d, 0x58, 0x33, 0x44,
     0x3a, 0xdd, 0xe9, 0xfb, 0x50, 0x47, 0xc8, 0xd7, 0x81, 0x9b, 0xe5, 0x1b, 0x17, 0x54, 0x86,
     0x2b, 0xef, 0xf4, 0x29, 0x32, 0x0e, 0x7c, 0x23, 0x15, 0xeb, 0xe6, 0x3c, 0x35, 0xe2, 0x96,
     0x68, 0x3f, 0x0b, 0x43, 0xce, 0xde, 0x9c, 0xbe, 0x4f, 0x45, 0x72, 0x76, 0xb5, 0x10, 0xe3,
     0xdf, 0x92, 0xd2, 0xa8, 0x48, 0x91, 0xb9, 0xac, 0xbf, 0x49, 0xb2, 0x99, 0x64, 0x70, 0xea,
     0xf3, 0x3e, 0x63, 0x14, 0xae, 0xed, 0xaa, 0x24, 0xfe, 0x3d, 0xcb, 0xb0, 0x09, 0x38, 0x36,
     0x05},
    {0xc4, 0xf0, 0x28, 0x49, 0x55, 0x4a, 0xf5, 0xfd, 0x75, 0xaf, 0x20, 0x69, 0xc8, 0x43, 0x86,
     0x6b, 0xc9, 0xa8, 0xc6, 0x54, 0x4c, 0xdd, 0x02, 0x5b, 0xe8, 0x9b, 0x59, 0x77, 0x34, 0xd7,
     0xc0, 0x51, 0x5f, 0xf3, 0x7e, 0xd4, 0xf1, 0x90, 0x81, 0xce, 0x19, 0x8a, 0x78, 0x33, 0xcd,
     0x97, 0x8c, 0xd6, 0x6a, 0x4b, 0x8f, 0xa4, 0x80, 0xdc, 0x1a, 0x17, 0x14, 0xc5, 0x07, 0x87,
     0x66, 0xad, 0x9d, 0x85, 0xb2, 0xf8, 0x8d, 0x98, 0xdf, 0x3e, 0x1f, 0x3f, 0x64, 0x58, 0x40,
     0xac, 0x6c, 0x5c, 0x08, 0x5d, 0x53, 0xba, 0xff, 0xd2, 0xa9, 0x2c, 0x25, 0xab, 0xe4, 0x32,
     0x38, 0x9a, 0xf9, 0xcb, 0xc2, 0x91, 0x67, 0xd0, 0xe3, 0x22, 0x29, 0x2d, 0x92, 0x48, 0xb4,
     0x0e, 0x99, 0x05, 0xa3, 0x6f, 0x0a, 0x15, 0xef, 0xd5, 0x10, 0x4f, 0xd8, 0xf6, 0x00, 0xe6,
     0x46, 0x2b, 0x31, 0x57, 0x83, 0x94, 0xae, 0x03, 0xeb, 0x8e, 0x13, 0x24, 0xa1, 0x1e, 0x5e,
     0xd1, 0x26, 0xd9, 0xa7, 0xca, 0x36, 0x6e, 0x71, 0x37, 0xee, 0xb1, 0xfa, 0x7c, 0x76, 0x06,
     0xb8, 0x23, 0xbe, 0x21, 0xbc, 0x9e, 0xc1, 0xda, 0x7a, 0x3b, 0x62, 0x27, 0x7b, 0xb0, 0xe5,
     0x63, 0x18, 0x82, 0x7f, 0x0f, 0xed, 0xa0, 0x2a, 0x9c, 0xbf, 0x11, 0xbd, 0xe0, 0x88, 0x0d,
     0x3a, 0x79, 0x52, 0x56, 0xf7, 0xb6, 0xd3, 0x09, 0x16, 0x1b, 0x70, 0xb3, 0x42, 0x60, 0x2f,
     0x1c, 0xa2, 0x9f, 0x72, 0x12, 0x45, 0x47, 0xbb, 0xe1, 0x0b, 0x01, 0x8b, 0x1d, 0xde, 0xec,
     0x0c, 0x4e, 0xe9, 0xcf, 0xcc, 0x95, 0x74, 0xf4, 0xa5, 0x93, 0xc7, 0xdb, 0x4d, 0xfb, 0x35,
     0x65, 0xfe, 0xe7, 0x39, 0xb5, 0xea, 0x96, 0xc3, 0x04, 0x41, 0x44, 0x84, 0xfc, 0x6d, 0x30,
     0xe2, 0xf2, 0x68, 0xb7, 0x89, 0x7d, 0x73, 0x3d, 0xb9, 0x5a, 0x50, 0xa6, 0x3c, 0x61, 0xaa,
     0x2e},
    {0x1a, 0x59, 0x9c, 0xad, 0xc8, 0xe4, 0x11, 0x54, 0xed, 0x37, 0x0f, 0x3a, 0xe6, 0x5f, 0x3c,
     0x4b, 0xb8, 0x15, 0x89, 0xb1, 0xe8, 0xda, 0x69, 0x77, 0x91, 0x56, 0x8b, 0xdb, 0x06, 0x24,
     0xcf, 0x18, 0xf8, 0xb0, 0x87, 0xdf, 0x8c, 0x35, 0xcb, 0x86, 0x53, 0x9d, 0xa4, 0x66, 0x4a,
     0x7a, 0x71, 0x0a, 0x48, 0x38, 0xff, 0xdc, 0x83, 0x20, 0xce, 0x98, 0x32, 0xf6, 0xd7, 0xaf,
     0x70, 0x5e, 0x73, 0x8a, 0x14, 0x72, 0x1e, 0xc1, 0x29, 0x79, 0x07, 0x08, 0xe9, 0x43, 0x46,
     0xd0, 0x2f, 0xde, 0x2a, 0x4f, 0x3d, 0x2c, 0x50, 0xb3, 0x75, 0xfc, 0x0b, 0x64, 0xae, 0x31,
     0x7b, 0x61, 0xa5, 0x30, 0xa0, 0x93, 0xd2, 0xbe, 0xc2, 0x55, 0xba, 0x6c, 0xf3, 0x62, 0x68,
     0xfd, 0xac, 0x3b, 0x95, 0x49, 0x1f, 0x6b, 0xb4, 0x85, 0xf7, 0xa6, 0x03, 0xec, 0x6e, 0x9a,
     0x81, 0x09, 0x0c, 0x6a, 0xee, 0x9e, 0x4e, 0xf0, 0xab, 0x2d, 0x7e, 0xa1, 0xe1, 0xbb, 0xc9,
     0xbc, 0x41, 0xf2, 0xfa, 0x2e, 0x1b, 0xdd, 0x27, 0x34, 0xd3, 0x60, 0x04, 0xb5, 0x01, 0xd6,
     0x40, 0xf9, 0xd5, 0x02, 0x47, 0xd9, 0xd8, 0xe0, 0x8f, 0x2b, 0xfb, 0xb7, 0xc5, 0xeb, 0x57,
     0x16, 0xe5, 0x78, 0x8d, 0xf4, 0x00, 0xcd, 0x82, 0x39, 0xc6, 0x96, 0xbd, 0xbf, 0xe3, 0x36,
     0x45, 0x0e, 0x26, 0x1d, 0x63, 0xe7, 0x84, 0x3e, 0xb6, 0x9b, 0x22, 0xa3, 0xf5, 0x8e, 0x23,
     0x6d, 0xc3, 0x99, 0x7d, 0x90, 0x97, 0x10, 0x25, 0x80, 0xd4, 0x4c, 0xe2, 0x74, 0xcc, 0xb2,
     0x5c, 0x33, 0xc7, 0xea, 0x05, 0x12, 0x3f, 0x51, 0xa8, 0xfe, 0xf1, 0x1c, 0x42, 0xca, 0xd1,
     0x76, 0x28, 0x6f, 0x92, 0xa7, 0x67, 0xa9, 0x19, 0xa2, 0x44, 0x5b, 0xaa, 0xef, 0x58, 0x7f,
     0x21, 0xc0, 0x88, 0x65, 0xb9, 0x5d, 0x4d, 0x0d, 0x5a, 0xc4, 0x13, 0x52, 0x7c, 0x9f, 0x94,
     0x17},
    {0xc7, 0x2b, 0x82, 0x61, 0x5b, 0xd0, 0x96, 0x84, 0xd3, 0x4a, 0x70, 0xa1, 0x9b, 0x59, 0x33,
     0x9f, 0xc0, 0x20, 0x14, 0x53, 0x29, 0x17, 0xc5, 0x0b, 0xc9, 0x7b, 0x97, 0x02, 0x0d, 0x3a,
     0x1e, 0x7c, 0x3f, 0x6b, 0x52, 0xe8, 0x75, 0x3d, 0xf6, 0xe4, 0x0c, 0x8a, 0x4f, 0xc3, 0x5f,
     0x26, 0x65, 0x73, 0x31, 0x23, 0x28, 0x48, 0x74, 0xaa, 0xa7, 0x36, 0x09, 0xb1, 0xe2, 0x91,
     0x04, 0x51, 0x22, 0xfc, 0x08, 0xa6, 0x05, 0xa4, 0xf1, 0x12, 0x1c, 0x19, 0xeb, 0x40, 0x37,
     0xc2, 0xa0, 0x41, 0x1d, 0xd4, 0xdc, 0x07, 0x43, 0x8f, 0x47, 0xaf, 0xd1, 0x2e, 0x98, 0xab,
     0x01, 0xba, 0xf0, 0x66, 0x68, 0xac, 0xf9, 0xe7, 0x69, 0xb6, 0xcb, 0x8d, 0x78, 0x87, 0x15,
     0x03, 0xd5, 0xdf, 0xa3, 0x1a, 0x9d, 0x6a, 0xea, 0x2f, 0x94, 0x4e, 0x9e, 0x42, 0xd7, 0xb8,
     0x38, 0x92, 0xd8, 0xbb, 0xde, 0xdd, 0x9a, 0xbc, 0xb0, 0x4c, 0x79, 0xf4, 0x58, 0x3e, 0xe9,
     0x83, 0x81, 0xff, 0xe3, 0x55, 0xfd, 0x5d, 0xb2, 0xef, 0x9c, 0x6d, 0x54, 0x99, 0x60, 0xda,
     0x3b, 0xec, 0xfa, 0x11, 0xd6, 0xc4, 0x2a, 0xed, 0x4b, 0xae, 0x13, 0xbf, 0xb9, 0x06, 0x8b,
     0xe0, 0x1f, 0x7f, 0x5a, 0xad, 0x90, 0x39, 0x0f, 0xf3, 0xbd, 0x46, 0x6c, 0x2c, 0xf2, 0xf8,
     0xfe, 0xd9, 0xe6, 0x72, 0x0e, 0x89, 0xbe, 0x5e, 0xc6, 0xa8, 0xcf, 0xf5, 0x57, 0x7e, 0x8c,
     0xb7, 0xe1, 0x88, 0x7a, 0xc8, 0x1b, 0x18, 0xdb, 0x6f, 0x35, 0xd2, 0x16, 0x32, 0x64, 0x63,
     0xa5, 0x8e, 0xf7, 0xb4, 0x76, 0x95, 0x86, 0x7d, 0xe5, 0xa9, 0x5c, 0x85, 0x00, 0xc1, 0x93,
     0x4d, 0xfb, 0x30, 0xa2, 0xb5, 0x25, 0x34, 0x10, 0x77, 0x3c, 0x67, 0x71, 0x2d, 0x44, 0x45,
     0x56, 0x0a, 0x50, 0xb3, 0xcd, 0x62, 0x80, 0xce, 0x21, 0x49, 0x24, 0xca, 0xee, 0x27, 0x6e,
     0xcc},
    {0xa5, 0xb0, 0x6d, 0xb2, 0x51, 0x55, 0x1f, 0xbf, 0x3e, 0x8d, 0xdd, 0x19, 0x92, 0xea, 0x1b,
     0xbd, 0x32, 0x65, 0x29, 0xa4, 0x89, 0x67, 0xb1, 0x90, 0x68, 0x00, 0xda, 0x0d, 0xa6, 0x59,
     0x54, 0xf2, 0x10, 0x14, 0x2f, 0x45, 0xe0, 0x3b, 0x23, 0xfa, 0xd7, 0x50, 0xac, 0x93, 0xe6,
     0x43, 0x01, 0x0a, 0x5c, 0x78, 0x70, 0x98, 0x46, 0xa9, 0x7b, 0xf3, 0x95, 0x07, 0x2a, 0xd3,
     0x74, 0xb3, 0x3f, 0xa3, 0x60, 0x82, 0x39, 0x4e, 0x34, 0x48, 0xc0, 0x1c, 0xf6, 0xc2, 0x91,
     0x64, 0x4d, 0x3c, 0xf8, 0x9d, 0x35, 0x9a, 0x94, 0xe3, 0x7a, 0xf0, 0xf9, 0x6e, 0xb9, 0x12,
     0xb8, 0x04, 0x2d, 0x02, 0x28, 0x13, 0x85, 0x72, 0x80, 0x87, 0xdb, 0x2b, 0xf1, 0x4f, 0x26,
     0xa2, 0xe1, 0x49, 0x7e, 0x9c, 0xcc, 0xa7, 0xb6, 0xa0, 0xd0, 0x9b, 0x36, 0x77, 0xad, 0x8b,
     0x6b, 0x4a, 0x03, 0x1d, 0x05, 0x8a, 0x06, 0x4b, 0xaf, 0xe5, 0x31, 0xb5, 0xd4, 0xc6, 0x0c,
     0x66, 0xba, 0x83, 0xfd, 0x09, 0x0f, 0xae, 0x71, 0xb7, 0x6f, 0xdc, 0x41, 0xe8, 0x17, 0x8e,
     0x40, 0x7f, 0x62, 0x30, 0xff, 0xa8, 0x84, 0x25, 0xfb, 0x16, 0xce, 0x37, 0x44, 0xab, 0x99,
     0x1e, 0xeb, 0x18, 0x3a, 0x47, 0xf7, 0x5f, 0x81, 0xcf, 0xed, 0x58, 0x2c, 0x6c, 0xfe, 0x9e,
     0x57, 0x53, 0x97, 0x20, 0xca, 0x79, 0x1a, 0x5a, 0x88, 0xf5, 0x69, 0x9f, 0xe7, 0xd9, 0x0e,
     0xbe, 0x42, 0xdf, 0x56, 0xe4, 0x4c, 0x22, 0xaa, 0x73, 0x0b, 0x15, 0xc5, 0xee, 0xfc, 0xc7,
     0xd6, 0xcb, 0xcd, 0x8c, 0xe2, 0x76, 0x21, 0xe9, 0xd1, 0xec, 0xc8, 0x7d, 0xd8, 0x8f, 0x61,
     0x7c, 0x2e, 0xbc, 0xde, 0xb4, 0x75, 0xd2, 0xc4, 0x63, 0x3d, 0xa1, 0x5e, 0x5d, 0x6a, 0x08,
     0x24, 0xc9, 0x27, 0xbb, 0xef, 0x33, 0x86, 0x5b, 0xd5, 0x38, 0x52, 0x11, 0xf4, 0xc3, 0x96,
     0xc1},
    {0x34, 0x5a, 0xdb, 0x2c, 0x59, 0x57, 0x12, 0x2b, 0x30, 0xc2, 0xa0, 0x92, 0xbf, 0xed, 0xbc,
     0x45, 0xde, 0x27, 0x9b, 0x96, 0xd3, 0xe6, 0xc5, 0xeb, 0xd8, 0x24, 0x4b, 0xa4, 0x21, 0xcc,
     0xa8, 0xd6, 0xce, 0x3c, 0xba, 0xb1, 0x09, 0xe0, 0xd7, 0x32, 0x66, 0x4a, 0x83, 0x1d, 0x19,
     0xca, 0x89, 0x67, 0x0f, 0x42, 0x07, 0x71, 0xe9, 0xbb, 0x44, 0x5e, 0x85, 0x17, 0xc4, 0xae,
     0x9c, 0x3f, 0x6b, 0x78, 0xe7, 0x6d, 0x02, 0xa7, 0xfe, 0x33, 0xe3, 0xd9, 0x0a, 0x7d, 0xea,
     0xf1, 0x18, 0x87, 0x7b, 0x62, 0x03, 0x79, 0x52, 0x23, 0x00, 0x3e, 0x25, 0xb9, 0xdd, 0x16,
     0x68, 0x3b, 0x1f, 0x90, 0xa6, 0x2a, 0xc6, 0x29, 0x91, 0x8a, 0x9d, 0xef, 0x1e, 0x84, 0x76,
     0xee, 0x4f, 0x39, 0xfb, 0x11, 0x1b, 0x0b, 0x93, 0xad, 0x49, 0xb7, 0x05, 0xe1, 0x4d, 0xcb,
     0xe8, 0x38, 0xd0, 0x55, 0xf2, 0xf7, 0x0d, 0x8b, 0x65, 0xcd, 0xfa, 0xd4, 0x9e, 0xc9, 0x81,
     0x4e, 0x14, 0xc8, 0x26, 0xb6, 0xf9, 0xaa, 0xf5, 0x80, 0xf8, 0x6a, 0x98, 0xab, 0x58, 0xf3,
     0xb8, 0x8e, 0xb5, 0x97, 0x43, 0x72, 0xa2, 0xda, 0x64, 0xc1, 0x40, 0x5c, 0x13, 0xb0, 0xe5,
     0xbd, 0x08, 0x9f, 0x1c, 0x7e, 0x8f, 0x06, 0xbe, 0x6e, 0x50, 0x1a, 0x2f, 0x37, 0xa1, 0xfc,
     0x10, 0x2e, 0x70, 0x53, 0x04, 0x20, 0x63, 0x48, 0xe2, 0xfd, 0x6f, 0x7a, 0x75, 0x61, 0xb3,
     0x35, 0x3a, 0xcf, 0x5b, 0x88, 0x82, 0x51, 0xd2, 0x47, 0xa5, 0xa9, 0x74, 0x6c, 0x31, 0x94,
     0x7c, 0x9a, 0xc0, 0xec, 0x15, 0x0e, 0x28, 0x01, 0x2d, 0xc3, 0xf0, 0xb4, 0xe4, 0x8d, 0xdc,
     0xac, 0x3d, 0x5f, 0x86, 0xc7, 0x95, 0x22, 0xf4, 0xb2, 0xa3, 0x54, 0x46, 0xd1, 0x77, 0x8c,
     0x0c, 0xff, 0xaf, 0x56, 0x5d, 0x36, 0x69, 0x7f, 0x99, 0x4c, 0xd5, 0x60, 0x73, 0xdf, 0x41,
     0xf6},
    {0x04, 0xda, 0x79, 0x63, 0x1e, 0xbd, 0xea, 0xe3, 0x0b, 0x65, 0x25, 0x01, 0xcd, 0xa9, 0x92,
     0xed, 0x18, 0x75, 0x57, 0x30, 0x89, 0x03, 0x09, 0x6a, 0xdc, 0xc7, 0x98, 0xa4, 0x50, 0x91,
     0x1f, 0xb1, 0x0c, 0x77, 0x85, 0x66, 0xca, 0x12, 0x1c, 0x67, 0xc2, 0xe0, 0x17, 0x83, 0x59,
     0x9d, 0xd5, 0x22, 0x82, 0x56, 0xa8, 0x9f, 0xc6, 0x60, 0x48, 0xb3, 0x11, 0xfc, 0xa3, 0x28,
     0xfb, 0x06, 0xdd, 0x5d, 0xba, 0x29, 0x7a, 0x4f, 0xe8, 0xfe, 0xe9, 0x10, 0xcb, 0xf3, 0x93,
     0x7b, 0x6c, 0x69, 0x54, 0xe7, 0x44, 0xa2, 0x84, 0x1d, 0x8d, 0xce, 0xff, 0xfa, 0x1a, 0x87,
     0x90, 0x74, 0xa1, 0xf8, 0x14, 0xaa, 0xbc, 0xc0, 0xcf, 0x31, 0xb4, 0xd9, 0xbf, 0xd8, 0x5e,
     0x26, 0x2d, 0xd0, 0xe4, 0x3f, 0x19, 0xd6, 0x8c, 0x2f, 0xab, 0x39, 0x58, 0x72, 0x6e, 0xdf,
     0x3b, 0xe6, 0x3c, 0xb6, 0x62, 0x88, 0xde, 0x40, 0xb2, 0x8f, 0x9b, 0x7c, 0x95, 0x43, 0xd1,
     0x9e, 0xac, 0x9c, 0xd4, 0x23, 0xe1, 0x0e, 0x4b, 0x53, 0x33, 0x46, 0x20, 0x13, 0x34, 0x1b,
     0x97, 0xf7, 0xf1, 0xc3, 0x61, 0x4a, 0x6f, 0x5a, 0x21, 0x7f, 0x70, 0x2e, 0x55, 0x41, 0x05,
     0xc5, 0xd7, 0x76, 0xe5, 0x27, 0x15, 0xec, 0x42, 0x5c, 0x4d, 0x78, 0x35, 0x8b, 0xef, 0xd2,
     0xee, 0xb5, 0xbe, 0xae, 0x02, 0x3a, 0xd3, 0x5f, 0xc4, 0x24, 0xf0, 0xf9, 0x51, 0x4e, 0xeb,
     0x00, 0x0f, 0xfd, 0xaf, 0x3e, 0xc1, 0x9a, 0x52, 0x86, 0x81, 0x80, 0x7e, 0xf6, 0x2b, 0xcc,
     0xb9, 0x7d, 0x68, 0xf2, 0xad, 0x99, 0xa7, 0x07, 0x2c, 0x73, 0x38, 0xb0, 0x6b, 0xb7, 0x8e,
     0x71, 0xa0, 0xf4, 0x3d, 0xa6, 0x0d, 0x37, 0xdb, 0x0a, 0x47, 0x36, 0x16, 0x96, 0x6d, 0x32,
     0x2a, 0x5b, 0xe2, 0x45, 0x94, 0xf5, 0xa5, 0x4c, 0xc8, 0x8a, 0x49, 0x64, 0xbb, 0x08, 0xc9,
     0xb8},
};

static const uint8_t access_code_table_1[5][10][100] = {
    {
        {11, 38, 3,  63, 36, 39, 79, 19, 87, 68, 76, 51, 20, 56, 77, 61, 52, 73, 74, 94,
         45, 31, 99, 28, 29, 90, 81, 96, 65, 75, 13, 32, 70, 21, 55, 33, 9,  15, 92, 14,
         82, 97, 78, 37, 49, 0,  80, 57, 58, 7,  1,  89, 98, 53, 64, 5,  6,  66, 43, 83,
         10, 50, 47, 84, 62, 71, 4,  67, 86, 42, 35, 34, 91, 12, 17, 69, 44, 48, 85, 30,
         16, 95, 54, 23, 46, 18, 88, 59, 40, 60, 41, 25, 27, 22, 2,  24, 72, 93, 26, 8},
        {28, 58, 74, 34, 6,  14, 16, 46, 87, 24, 59, 57, 23, 88, 75, 65, 79, 38, 82, 13,
         49, 99, 8,  94, 15, 19, 0,  96, 41, 95, 45, 35, 1,  91, 2,  52, 42, 76, 90, 84,
         20, 54, 4,  63, 25, 5,  47, 85, 93, 12, 51, 81, 71, 69, 22, 17, 36, 64, 77, 80,
         98, 53, 44, 18, 10, 68, 97, 61, 56, 70, 92, 27, 40, 9,  60, 7,  72, 21, 43, 3,
         33, 32, 50, 26, 67, 62, 39, 48, 73, 86, 29, 89, 37, 78, 55, 66, 31, 30, 11, 83},
        {4,  16, 22, 66, 37, 14, 47, 89, 59, 60, 51, 92, 71, 70, 96, 13, 17, 85, 58, 93,
         81, 69, 28, 90, 78, 39, 63, 88, 0,  75, 2,  53, 23, 99, 94, 68, 54, 74, 41, 29,
         8,  26, 50, 98, 82, 95, 42, 7,  24, 77, 30, 9,  21, 1,  87, 62, 46, 15, 43, 38,
         36, 55, 49, 57, 52, 56, 91, 65, 11, 84, 6,  73, 97, 33, 83, 27, 35, 25, 40, 32,
         18, 31, 86, 48, 45, 3,  79, 76, 72, 64, 44, 20, 80, 19, 10, 5,  61, 34, 67, 12},
        {80, 91, 71, 26, 75, 8,  22, 92, 7,  70, 65, 51, 89, 31, 81, 30, 83, 47, 44, 85,
         55, 19, 57, 87, 74, 6,  73, 40, 49, 32, 52, 78, 0,  12, 54, 15, 64, 28, 4,  24,
         68, 17, 72, 53, 1,  94, 58, 88, 11, 82, 43, 86, 60, 63, 99, 96, 37, 77, 67, 33,
         18, 5,  41, 59, 16, 36, 79, 97, 61, 23, 56, 48, 98, 38, 66, 21, 34, 29, 10, 3,
         93, 46, 50, 39, 14, 9,  2,  13, 69, 42, 62, 35, 27, 90, 25, 76, 20, 95, 45, 84},
        {48, 16, 54, 47, 9,  39, 81, 91, 33, 53, 63, 21, 50, 85, 97, 90, 49, 36, 84, 74,
         51, 76, 37, 67, 59, 58, 23, 20, 65, 82, 7,  77, 12, 31, 46, 1,  5,  14, 3,  30,
         94, 95, 2,  34, 70, 89, 40, 87, 43, 79, 64, 57, 68, 26, 56, 44, 88, 61, 0,  24,
         71, 18, 60, 4,  80, 96, 27, 15, 6,  13, 98, 29, 28, 25, 72, 93, 55, 75, 52, 66,
         11, 8,  86, 45, 22, 83, 17, 10, 35, 38, 73, 99, 62, 41, 19, 69, 78, 92, 42, 32},
        {23, 19, 88, 44, 5,  39, 75, 81, 30, 14, 49, 54, 62, 55, 18, 83, 77, 76, 74, 92,
         6,  95, 52, 36, 15, 27, 53, 38, 28, 50, 48, 99, 78, 67, 90, 87, 16, 41, 58, 65,
         79, 11, 68, 84, 24, 97, 64, 47, 9,  22, 43, 86, 37, 8,  33, 17, 93, 61, 25, 72,
         57, 98, 42, 80, 13, 89, 2,  12, 31, 56, 26, 85, 3,  29, 66, 63, 82, 10, 20, 94,
         51, 0,  1,  4,  21, 60, 34, 35, 32, 45, 59, 71, 46, 69, 7,  96, 91, 40, 70, 73},
        {89, 62, 33, 19, 21, 97, 15, 2,  83, 22, 65, 30, 55, 7,  63, 73, 39, 61, 44, 37,
         11, 26, 31, 79, 91, 0,  72, 68, 23, 87, 28, 24, 45, 74, 98, 14, 70, 54, 88, 42,
         35, 59, 46, 16, 27, 92, 69, 66, 94, 32, 75, 77, 64, 57, 50, 71, 10, 3,  67, 81,
         90, 58, 99, 5,  82, 85, 25, 52, 12, 8,  48, 49, 76, 96, 80, 20, 29, 34, 53, 51,
         86, 93, 38, 84, 9,  36, 6,  60, 1,  78, 13, 95, 41, 17, 47, 18, 43, 40, 4,  56},
        {40, 68, 88, 47, 43, 28, 67, 23, 42, 99, 48, 3,  12, 27, 79, 25, 6,  55, 19, 80,
         81, 62, 83, 69, 39, 73, 36, 30, 44, 82, 70, 52, 31, 34, 58, 74, 54, 2,  13, 45,
         93, 49, 75, 72, 29, 87, 5,  7,  17, 76, 90, 63, 84, 51, 59, 35, 20, 97, 22, 65,
         57, 66, 78, 86, 11, 9,  71, 98, 53, 56, 15, 46, 92, 0,  26, 21, 32, 38, 77, 91,
         4,  24, 61, 85, 94, 1,  96, 64, 8,  41, 33, 50, 18, 60, 10, 16, 37, 95, 14, 89},
        {96, 23, 99, 42, 94, 91, 19, 53, 41, 25, 39, 73, 70, 72, 33, 35, 88, 2,  63, 49,
         95, 60, 48, 97, 5,  54, 47, 40, 98, 18, 57, 28, 67, 92, 10, 79, 13, 76, 8,  55,
         90, 62, 50, 87, 65, 82, 84, 21, 0,  14, 45, 44, 20, 38, 17, 3,  81, 16, 58, 4,
         31, 29, 86, 15, 43, 64, 26, 52, 46, 69, 37, 68, 6,  22, 61, 7,  83, 71, 30, 75,
         85, 78, 24, 27, 89, 9,  80, 34, 66, 77, 36, 93, 56, 59, 1,  12, 51, 32, 11, 74},
        {75, 99, 97, 8,  15, 48, 6,  25, 60, 90, 91, 95, 23, 3,  89, 77, 22, 78, 94, 55,
         98, 35, 53, 96, 18, 52, 12, 16, 50, 20, 49, 9,  17, 13, 57, 44, 14, 47, 86, 56,
         88, 41, 29, 32, 70, 1,  62, 37, 85, 38, 59, 36, 5,  68, 71, 69, 67, 27, 39, 4,
         54, 0,  84, 45, 61, 73, 79, 93, 58, 66, 10, 76, 51, 92, 19, 87, 24, 7,  28, 2,
         11, 80, 81, 33, 64, 74, 46, 65, 26, 72, 40, 82, 34, 42, 21, 83, 31, 30, 43, 63},
    },
    {
        {98, 58, 34, 65, 83, 74, 88, 5,  89, 46, 80, 43, 18, 87, 9,  28, 71, 90, 4,  36,
         40, 11, 39, 31, 76, 92, 82, 48, 66, 41, 49, 99, 78, 79, 97, 86, 75, 68, 3,  7,
         62, 64, 26, 22, 13, 77, 54, 50, 10, 96, 15, 35, 94, 73, 57, 93, 16, 61, 37, 38,
         53, 2,  63, 23, 67, 72, 95, 70, 29, 33, 45, 47, 27, 24, 69, 44, 55, 85, 14, 8,
         91, 12, 42, 6,  84, 81, 19, 25, 32, 51, 1,  17, 52, 56, 60, 0,  59, 30, 21, 20},
        {26, 63, 99, 57, 77, 53, 9,  75, 76, 80, 46, 97, 37, 14, 1,  12, 35, 20, 0,  15,
         28, 19, 48, 41, 67, 30, 60, 69, 29, 34, 73, 10, 51, 47, 66, 82, 7,  98, 39, 96,
         8,  62, 42, 3,  95, 5,  11, 13, 90, 94, 32, 31, 83, 64, 36, 88, 72, 52, 38, 54,
         45, 17, 61, 81, 78, 44, 79, 55, 56, 86, 2,  40, 16, 24, 4,  71, 49, 33, 23, 92,
         84, 74, 65, 43, 87, 59, 89, 68, 22, 70, 25, 58, 21, 85, 6,  50, 27, 93, 91, 18},
        {22, 31, 11, 72, 37, 70, 90, 60, 24, 56, 28, 69, 54, 85, 5,  98, 1,  76, 59, 20,
         86, 32, 61, 49, 63, 42, 74, 53, 84, 3,  95, 23, 15, 36, 4,  81, 6,  21, 19, 27,
         17, 83, 30, 45, 25, 65, 10, 50, 80, 66, 46, 75, 93, 82, 78, 99, 97, 68, 8,  13,
         58, 94, 41, 14, 48, 52, 29, 79, 91, 89, 9,  55, 57, 2,  39, 92, 0,  44, 18, 62,
         73, 96, 34, 88, 16, 77, 71, 43, 33, 40, 7,  12, 87, 51, 26, 47, 64, 35, 67, 38},
        {0,  80, 63, 52, 49, 69, 15, 87, 55, 60, 22, 91, 31, 89, 78, 28, 48, 12, 10, 42,
         82, 23, 29, 18, 21, 2,  19, 7,  68, 37, 54, 90, 81, 43, 57, 94, 26, 95, 96, 88,
         14, 51, 79, 71, 66, 76, 34, 24, 30, 9,  62, 44, 77, 65, 6,  27, 4,  97, 38, 36,
         59, 3,  1,  50, 72, 46, 64, 35, 20, 11, 53, 13, 58, 39, 74, 8,  83, 75, 40, 98,
         17, 99, 85, 32, 92, 67, 84, 5,  25, 56, 16, 47, 70, 93, 86, 61, 73, 41, 45, 33},
        {64, 57, 56, 7,  86, 9,  65, 16, 1,  63, 71, 26, 53, 98, 69, 5,  84, 28, 36, 58,
         54, 99, 42, 74, 68, 3,  88, 22, 82, 97, 85, 45, 21, 66, 43, 59, 83, 51, 89, 87,
         31, 12, 95, 52, 60, 17, 80, 27, 72, 93, 10, 39, 91, 30, 75, 61, 24, 8,  23, 2,
         18, 73, 94, 6,  38, 44, 13, 40, 48, 4,  81, 37, 96, 46, 19, 49, 34, 50, 0,  20,
         14, 15, 25, 92, 33, 29, 77, 90, 78, 67, 62, 41, 35, 47, 79, 32, 11, 70, 76, 55},
        {24, 99, 28, 52, 64, 3,  63, 16, 15, 87, 47, 6,  59, 98, 13, 78, 57, 81, 56, 94,
         0,  37, 70, 73, 65, 83, 90, 92, 60, 82, 67, 40, 74, 34, 91, 2,  33, 85, 21, 54,
         12, 31, 84, 55, 53, 49, 36, 25, 39, 20, 29, 93, 51, 76, 42, 96, 71, 86, 95, 66,
         45, 19, 8,  58, 22, 69, 80, 79, 89, 17, 61, 18, 88, 38, 72, 75, 48, 30, 7,  10,
         11, 35, 23, 9,  26, 4,  62, 44, 1,  43, 46, 14, 41, 77, 97, 27, 68, 32, 5,  50},
        {90, 80, 22, 27, 16, 23, 11, 31, 8,  75, 54, 82, 68, 66, 10, 40, 95, 99, 14, 42,
         56, 88, 12, 55, 38, 6,  79, 84, 26, 92, 4,  67, 48, 5,  46, 77, 19, 53, 97, 34,
         64, 73, 58, 47, 18, 39, 81, 59, 74, 62, 87, 98, 50, 1,  25, 9,  72, 69, 61, 60,
         86, 3,  24, 28, 45, 30, 96, 36, 57, 83, 89, 63, 0,  33, 17, 7,  94, 15, 43, 2,
         44, 41, 20, 85, 32, 65, 93, 49, 91, 52, 71, 37, 35, 13, 21, 51, 70, 29, 78, 76},
        {95, 50, 72, 0,  68, 98, 49, 53, 56, 41, 54, 22, 57, 78, 66, 31, 52, 29, 86, 30,
         62, 26, 32, 46, 42, 48, 14, 21, 88, 94, 77, 92, 7,  63, 91, 28, 93, 38, 90, 71,
         34, 25, 11, 83, 55, 70, 97, 82, 89, 76, 10, 99, 9,  45, 60, 39, 44, 16, 17, 37,
         47, 79, 33, 36, 59, 8,  80, 23, 1,  18, 64, 51, 61, 81, 75, 40, 35, 73, 13, 65,
         12, 4,  19, 85, 96, 6,  2,  58, 27, 43, 5,  87, 20, 15, 3,  24, 84, 67, 74, 69},
        {38, 33, 29, 88, 49, 47, 60, 69, 75, 12, 44, 89, 35, 45, 23, 30, 21, 28, 65, 86,
         81, 40, 93, 97, 67, 2,  94, 9,  61, 92, 90, 32, 62, 36, 58, 51, 37, 73, 50, 63,
         39, 43, 16, 71, 46, 91, 13, 7,  20, 72, 41, 59, 70, 48, 10, 52, 5,  34, 76, 15,
         87, 6,  98, 18, 57, 77, 24, 79, 27, 19, 3,  0,  8,  95, 74, 64, 42, 4,  68, 31,
         84, 54, 99, 25, 1,  80, 85, 26, 83, 11, 56, 55, 78, 66, 82, 14, 53, 22, 17, 96},
        {26, 12, 62, 5,  78, 53, 31, 46, 51, 8,  69, 80, 32, 68, 76, 42, 29, 87, 28, 75,
         40, 91, 58, 7,  88, 92, 82, 96, 70, 50, 47, 65, 85, 3,  48, 73, 90, 89, 97, 84,
         81, 39, 43, 79, 64, 54, 2,  41, 38, 10, 24, 22, 25, 93, 44, 23, 49, 37, 14, 95,
         72, 74, 15, 11, 55, 98, 99, 0,  9,  16, 18, 20, 63, 30, 57, 19, 4,  17, 67, 35,
         60, 45, 59, 56, 36, 77, 66, 33, 27, 71, 86, 1,  13, 34, 21, 61, 6,  94, 52, 83},
    },
    {
        {10, 87, 64, 11, 25, 97, 93, 18, 99, 38, 17, 72, 50, 23, 90, 57, 98, 12, 29, 46,
         19, 77, 42, 15, 73, 52, 53, 89, 35, 20, 9,  41, 79, 13, 95, 48, 85, 54, 61, 94,
         0,  74, 62, 40, 78, 68, 24, 28, 86, 21, 59, 14, 82, 84, 92, 58, 34, 31, 6,  16,
         75, 81, 43, 47, 7,  3,  2,  37, 67, 8,  66, 22, 30, 32, 71, 44, 70, 1,  36, 26,
         33, 63, 80, 83, 91, 76, 56, 39, 69, 55, 96, 60, 27, 49, 65, 88, 5,  4,  51, 45},
        {73, 87, 48, 43, 71, 40, 88, 23, 60, 35, 30, 5,  75, 25, 59, 95, 58, 79, 4,  89,
         96, 17, 38, 6,  39, 9,  68, 81, 3,  90, 93, 99, 16, 42, 21, 45, 74, 84, 77, 65,
         63, 98, 11, 51, 0,  33, 91, 22, 69, 34, 31, 20, 46, 2,  76, 54, 15, 62, 13, 70,
         92, 55, 82, 47, 78, 7,  24, 27, 86, 1,  56, 61, 12, 44, 85, 57, 49, 19, 18, 67,
         66, 52, 72, 53, 83, 41, 64, 50, 26, 94, 32, 80, 28, 10, 37, 14, 8,  97, 29, 36},
        {60, 50, 53, 78, 63, 90, 11, 33, 21, 24, 20, 55, 8,  25, 6,  58, 3,  98, 44, 82,
         96, 14, 1,  59, 92, 75, 51, 36, 30, 64, 72, 40, 16, 94, 2,  74, 93, 85, 12, 10,
         43, 32, 42, 39, 79, 97, 17, 38, 89, 29, 68, 52, 49, 0,  34, 19, 70, 84, 54, 9,
         23, 71, 65, 28, 83, 56, 67, 57, 13, 18, 77, 5,  4,  88, 41, 22, 46, 76, 48, 61,
         81, 45, 86, 35, 47, 87, 91, 99, 73, 66, 27, 37, 31, 15, 7,  80, 62, 95, 69, 26},
        {49, 73, 63, 66, 38, 35, 32, 96, 87, 26, 36, 92, 58, 6,  17, 47, 29, 84, 11, 18,
         67, 45, 78, 4,  52, 81, 59, 30, 91, 54, 56, 89, 48, 46, 20, 79, 1,  62, 9,  53,
         10, 95, 88, 34, 40, 80, 41, 64, 83, 55, 43, 7,  24, 61, 77, 5,  14, 93, 16, 21,
         85, 39, 76, 50, 57, 65, 37, 60, 28, 19, 2,  97, 42, 33, 13, 68, 90, 25, 69, 99,
         98, 74, 3,  8,  12, 15, 82, 71, 31, 23, 75, 27, 51, 94, 86, 0,  44, 22, 72, 70},
        {30, 32, 52, 21, 15, 79, 53, 40, 56, 44, 55, 6,  63, 39, 61, 4,  93, 43, 23, 99,
         38, 66, 88, 18, 1,  86, 33, 9,  82, 76, 70, 51, 48, 69, 85, 11, 5,  91, 59, 77,
         49, 75, 22, 87, 65, 41, 26, 50, 47, 98, 57, 10, 58, 62, 46, 28, 20, 71, 78, 95,
         0,  72, 80, 73, 92, 36, 96, 37, 68, 2,  35, 83, 90, 25, 13, 24, 34, 42, 45, 74,
         67, 16, 84, 97, 19, 64, 27, 14, 31, 12, 54, 60, 3,  8,  17, 89, 81, 94, 7,  29},
        {1,  18, 25, 13, 57, 53, 92, 95, 94, 88, 10, 82, 34, 83, 7,  28, 55, 11, 5,  58,
         8,  9,  74, 99, 52, 32, 62, 45, 65, 50, 41, 56, 96, 44, 38, 47, 3,  39, 81, 19,
         2,  22, 49, 12, 40, 67, 89, 76, 64, 70, 61, 21, 31, 54, 51, 17, 46, 30, 24, 60,
         66, 26, 77, 63, 37, 35, 23, 6,  4,  87, 79, 97, 20, 48, 36, 85, 73, 71, 27, 43,
         0,  15, 69, 78, 59, 86, 75, 33, 42, 84, 91, 93, 68, 80, 16, 98, 90, 72, 14, 29},
        {30, 16, 10, 67, 83, 81, 42, 94, 35, 59, 22, 5,  53, 61, 1,  96, 68, 45, 95, 66,
         36, 37, 97, 87, 77, 93, 86, 33, 49, 13, 43, 14, 0,  34, 7,  2,  41, 21, 31, 32,
         76, 55, 62, 72, 90, 71, 38, 23, 46, 12, 51, 19, 6,  44, 52, 48, 73, 24, 29, 74,
         85, 99, 80, 28, 47, 9,  39, 84, 64, 57, 75, 98, 88, 26, 17, 63, 27, 56, 69, 8,
         54, 25, 91, 78, 3,  50, 65, 70, 11, 4,  92, 60, 40, 58, 15, 89, 82, 18, 79, 20},
        {60, 88, 79, 35, 40, 43, 52, 4,  17, 31, 84, 44, 50, 94, 91, 38, 87, 25, 92, 62,
         14, 97, 37, 18, 86, 28, 65, 90, 19, 29, 30, 75, 68, 49, 69, 11, 59, 41, 89, 33,
         47, 54, 98, 42, 80, 56, 78, 99, 23, 82, 9,  48, 21, 1,  63, 22, 58, 95, 10, 12,
         26, 74, 85, 13, 8,  27, 24, 53, 61, 34, 64, 71, 66, 32, 83, 73, 15, 67, 0,  20,
         16, 6,  77, 45, 5,  93, 76, 39, 57, 2,  96, 46, 51, 3,  55, 7,  81, 70, 36, 72},
        {35, 56, 77, 58, 23, 83, 91, 81, 53, 70, 20, 74, 84, 50, 79, 51, 88, 44, 45, 71,
         37, 26, 54, 48, 27, 43, 0,  12, 95, 97, 1,  63, 67, 98, 59, 40, 13, 19, 31, 87,
         99, 16, 57, 30, 17, 92, 55, 68, 5,  46, 64, 8,  7,  42, 90, 33, 29, 9,  85, 24,
         2,  69, 32, 10, 21, 65, 39, 86, 52, 62, 76, 89, 82, 6,  78, 4,  47, 28, 3,  75,
         41, 15, 18, 14, 66, 73, 38, 80, 61, 49, 11, 22, 34, 93, 36, 25, 94, 96, 60, 72},
        {6,  90, 16, 43, 20, 55, 94, 8,  62, 59, 47, 32, 81, 67, 42, 35, 71, 19, 54, 49,
         2,  88, 38, 5,  53, 77, 85, 11, 73, 34, 3,  72, 95, 58, 82, 64, 44, 29, 93, 14,
         56, 98, 4,  37, 45, 75, 86, 60, 87, 7,  31, 17, 89, 97, 10, 70, 36, 99, 46, 63,
         76, 41, 48, 84, 9,  52, 1,  24, 83, 25, 68, 18, 50, 26, 30, 27, 61, 0,  91, 33,
         51, 40, 79, 39, 15, 74, 28, 78, 69, 96, 57, 65, 21, 80, 22, 23, 12, 13, 92, 66},
    },
    {
        {93, 42, 18, 65, 28, 87, 39, 35, 71, 23, 96, 90, 15, 58, 78, 33, 92, 88, 49, 64,
         24, 84, 77, 8,  97, 50, 4,  53, 27, 83, 95, 31, 80, 47, 86, 55, 11, 40, 37, 14,
         34, 60, 54, 12, 94, 9,  41, 2,  26, 10, 6,  57, 75, 63, 32, 43, 13, 52, 82, 73,
         20, 30, 17, 5,  3,  68, 51, 89, 62, 79, 69, 70, 66, 45, 25, 22, 85, 0,  91, 76,
         38, 7,  99, 61, 29, 98, 16, 36, 44, 67, 59, 56, 48, 81, 21, 46, 74, 72, 19, 1},
        {78, 91, 97, 77, 75, 85, 32, 2,  40, 86, 38, 18, 56, 47, 50, 87, 27, 92, 64, 39,
         98, 23, 33, 72, 84, 58, 16, 99, 19, 65, 55, 73, 74, 42, 4,  48, 95, 8,  51, 3,
         37, 82, 96, 69, 14, 44, 12, 21, 76, 70, 36, 15, 71, 41, 20, 31, 54, 13, 0,  9,
         94, 67, 1,  60, 81, 61, 11, 6,  90, 5,  49, 10, 34, 7,  35, 30, 25, 88, 79, 93,
         66, 62, 22, 24, 52, 17, 89, 45, 83, 57, 28, 46, 63, 68, 26, 29, 80, 59, 43, 53},
        {78, 91, 97, 77, 75, 85, 32, 2,  40, 86, 38, 18, 56, 47, 50, 87, 27, 92, 64, 39,
         98, 23, 33, 72, 84, 58, 16, 99, 19, 65, 55, 73, 74, 42, 4,  48, 95, 8,  51, 3,
         37, 82, 96, 69, 14, 44, 12, 21, 76, 70, 36, 15, 71, 41, 20, 31, 54, 13, 0,  9,
         94, 67, 1,  60, 81, 61, 11, 6,  90, 5,  49, 10, 34, 7,  35, 30, 25, 88, 79, 93,
         66, 62, 22, 24, 52, 17, 89, 45, 83, 57, 28, 46, 63, 68, 26, 29, 80, 59, 43, 53},
        {41, 65, 16, 86, 77, 67, 51, 81, 50, 25, 90, 87, 98, 99, 23, 9,  4,  97, 39, 36,
         26, 42, 13, 66, 82, 22, 47, 88, 49, 46, 59, 78, 20, 19, 7,  93, 56, 84, 40, 61,
         89, 21, 74, 1,  54, 44, 34, 6,  28, 8,  43, 76, 48, 71, 85, 38, 83, 18, 24, 79,
         68, 80, 45, 33, 91, 27, 32, 70, 95, 3,  58, 60, 73, 10, 75, 52, 64, 2,  94, 30,
         17, 55, 62, 35, 11, 12, 53, 63, 14, 31, 57, 0,  37, 72, 92, 15, 5,  29, 69, 96},
        {74, 50, 44, 80, 11, 46, 39, 54, 24, 3,  7,  62, 41, 8,  75, 23, 57, 82, 51, 86,
         97, 79, 22, 60, 42, 14, 28, 67, 32, 73, 48, 56, 89, 26, 25, 77, 21, 68, 10, 2,
         58, 76, 92, 95, 38, 29, 43, 35, 12, 16, 55, 17, 63, 91, 45, 64, 59, 13, 47, 31,
         83, 5,  99, 49, 78, 71, 96, 53, 36, 90, 1,  66, 15, 0,  85, 65, 27, 4,  98, 94,
         6,  84, 72, 30, 70, 20, 61, 69, 37, 93, 34, 87, 9,  52, 88, 81, 33, 19, 40, 18},
        {35, 67, 27, 53, 26, 79, 20, 46, 38, 4,  72, 84, 70, 58, 65, 91, 92, 21, 32, 71,
         54, 24, 89, 0,  37, 8,  22, 81, 12, 87, 43, 18, 82, 17, 33, 76, 25, 13, 74, 51,
         99, 3,  55, 60, 19, 73, 86, 62, 93, 52, 31, 64, 96, 66, 14, 40, 42, 69, 45, 6,
         61, 34, 41, 59, 49, 10, 39, 2,  75, 80, 15, 94, 7,  23, 95, 78, 90, 5,  1,  28,
         56, 30, 9,  98, 44, 48, 68, 77, 47, 11, 63, 83, 88, 36, 97, 29, 57, 50, 16, 85},
        {8,  51, 32, 96, 34, 24, 88, 54, 87, 83, 45, 99, 49, 30, 55, 61, 95, 60, 59, 76,
         57, 5,  19, 56, 89, 66, 27, 94, 14, 6,  21, 58, 43, 74, 10, 2,  17, 62, 47, 16,
         69, 84, 63, 39, 4,  92, 35, 48, 53, 64, 71, 50, 72, 28, 42, 46, 91, 23, 15, 40,
         11, 78, 29, 86, 13, 90, 85, 20, 65, 93, 73, 80, 41, 37, 82, 79, 52, 9,  97, 38,
         75, 25, 44, 7,  26, 12, 22, 0,  33, 1,  31, 68, 70, 67, 98, 18, 77, 36, 3,  81},
        {34, 17, 91, 45, 63, 64, 1,  71, 98, 78, 94, 3,  99, 12, 15, 93, 69, 19, 61, 80,
         92, 81, 33, 51, 40, 10, 75, 24, 5,  87, 73, 46, 52, 86, 4,  70, 89, 56, 2,  67,
         72, 58, 49, 84, 29, 18, 22, 38, 95, 36, 43, 35, 37, 85, 57, 8,  76, 7,  27, 28,
         55, 74, 42, 13, 77, 31, 60, 39, 48, 68, 97, 79, 44, 54, 88, 82, 21, 66, 9,  23,
         59, 50, 47, 16, 83, 25, 6,  30, 41, 96, 90, 14, 62, 20, 65, 11, 26, 32, 53, 0},
        {7,  51, 77, 80, 0,  53, 56, 27, 2,  78, 28, 32, 26, 22, 73, 93, 36, 54, 64, 99,
         60, 50, 21, 11, 39, 42, 81, 8,  1,  79, 61, 5,  15, 31, 59, 33, 20, 94, 23, 88,
         69, 17, 35, 95, 40, 75, 85, 87, 43, 47, 89, 12, 71, 72, 9,  83, 67, 38, 90, 82,
         29, 10, 37, 91, 97, 74, 6,  86, 30, 63, 24, 49, 3,  13, 4,  57, 76, 70, 98, 34,
         58, 52, 96, 84, 25, 55, 44, 46, 18, 65, 62, 68, 48, 66, 41, 19, 14, 45, 16, 92},
        {96, 2,  76, 15, 31, 22, 71, 38, 88, 26, 67, 0,  21, 10, 58, 39, 63, 77, 23, 50,
         48, 19, 78, 30, 93, 91, 14, 12, 28, 11, 53, 73, 60, 61, 35, 79, 57, 70, 40, 20,
         56, 32, 65, 64, 68, 55, 82, 94, 45, 95, 66, 7,  43, 16, 37, 99, 72, 62, 13, 4,
         47, 8,  98, 89, 46, 29, 51, 85, 74, 17, 97, 84, 33, 18, 25, 83, 69, 44, 87, 49,
         92, 9,  90, 36, 41, 81, 59, 54, 34, 6,  42, 5,  80, 3,  1,  86, 27, 52, 24, 75},
    },
    {
        {61, 85, 41, 37, 12, 25, 27, 17, 92, 52, 44, 66, 13, 15, 19, 78, 77, 9,  40, 20,
         58, 43, 76, 24, 59, 42, 28, 30, 96, 86, 62, 89, 67, 35, 45, 6,  36, 50, 74, 26,
         84, 95, 7,  68, 97, 79, 51, 16, 80, 3,  82, 2,  93, 21, 31, 98, 18, 60, 39, 72,
         54, 65, 73, 32, 5,  70, 99, 10, 14, 71, 34, 4,  64, 33, 55, 48, 75, 87, 57, 81,
         22, 46, 69, 63, 90, 23, 38, 56, 8,  29, 83, 88, 11, 0,  47, 53, 91, 94, 49, 1},
        {35, 22, 67, 24, 94, 82, 12, 68, 30, 43, 58, 96, 27, 69, 65, 18, 7,  79, 14, 2,
         44, 60, 54, 47, 51, 83, 89, 3,  20, 11, 40, 85, 37, 48, 49, 8,  73, 15, 90, 93,
         70, 84, 34, 4,  86, 98, 17, 46, 72, 63, 26, 56, 97, 74, 91, 99, 36, 80, 81, 41,
         53, 88, 77, 21, 0,  23, 64, 76, 95, 33, 62, 1,  75, 87, 10, 66, 57, 6,  28, 25,
         42, 9,  50, 39, 29, 78, 13, 19, 31, 45, 55, 61, 38, 71, 59, 5,  92, 52, 32, 16},
        {70, 29, 50, 57, 31, 9,  59, 45, 87, 71, 98, 89, 77, 97, 86, 5,  21, 61, 47, 41,
         76, 37, 65, 12, 58, 75, 78, 91, 27, 63, 64, 83, 55, 95, 4,  11, 82, 23, 39, 40,
         42, 68, 69, 48, 54, 13, 99, 33, 26, 0,  66, 79, 46, 72, 49, 44, 25, 74, 73, 28,
         38, 10, 2,  85, 15, 19, 52, 94, 7,  36, 17, 32, 96, 3,  20, 30, 92, 51, 14, 90,
         24, 67, 43, 34, 93, 84, 62, 81, 1,  56, 53, 88, 80, 35, 22, 6,  18, 16, 8,  60},
        {62, 75, 38, 50, 52, 86, 53, 73, 99, 59, 26, 46, 48, 90, 64, 1,  65, 13, 30, 36,
         57, 16, 97, 91, 51, 33, 80, 67, 5,  25, 8,  96, 94, 84, 6,  89, 88, 20, 10, 85,
         41, 56, 9,  34, 63, 0,  18, 12, 42, 15, 87, 4,  61, 43, 82, 17, 98, 60, 92, 70,
         49, 71, 47, 54, 79, 83, 27, 74, 58, 2,  76, 93, 22, 69, 78, 44, 28, 95, 72, 68,
         7,  55, 29, 77, 14, 23, 31, 32, 3,  37, 11, 66, 35, 39, 24, 81, 19, 21, 40, 45},
        {65, 78, 7,  83, 80, 77, 71, 72, 22, 85, 63, 73, 44, 87, 86, 88, 41, 30, 95, 67,
         58, 21, 4,  5,  26, 27, 75, 31, 99, 52, 92, 64, 28, 8,  19, 98, 84, 34, 9,  48,
         60, 0,  56, 1,  62, 16, 91, 32, 89, 79, 40, 11, 54, 51, 43, 12, 45, 66, 23, 13,
         96, 81, 47, 36, 46, 93, 2,  69, 33, 3,  20, 6,  35, 18, 74, 68, 53, 37, 29, 61,
         90, 57, 14, 42, 24, 76, 10, 38, 97, 39, 25, 50, 49, 70, 55, 82, 15, 17, 59, 94},
        {11, 17, 21, 48, 63, 0,  73, 14, 10, 88, 2,  28, 6,  9,  19, 69, 81, 13, 35, 95,
         60, 56, 30, 47, 91, 92, 86, 29, 76, 50, 16, 25, 82, 93, 8,  5,  58, 94, 98, 20,
         74, 77, 4,  52, 97, 79, 27, 42, 36, 12, 26, 72, 71, 45, 24, 87, 1,  39, 22, 89,
         53, 31, 61, 37, 33, 18, 59, 43, 80, 15, 54, 38, 78, 90, 32, 83, 23, 44, 55, 66,
         64, 3,  67, 49, 84, 62, 51, 41, 46, 85, 96, 34, 99, 75, 7,  40, 70, 68, 65, 57},
        {43, 38, 48, 47, 74, 88, 64, 54, 59, 35, 29, 18, 53, 91, 68, 66, 12, 79, 55, 41,
         34, 36, 33, 94, 56, 87, 25, 6,  1,  8,  63, 96, 93, 44, 40, 65, 13, 77, 61, 85,
         99, 80, 11, 51, 14, 46, 5,  39, 92, 27, 75, 52, 72, 83, 19, 62, 32, 24, 82, 95,
         17, 37, 0,  15, 97, 4,  42, 86, 84, 3,  26, 81, 98, 9,  73, 22, 28, 78, 60, 76,
         16, 23, 71, 89, 31, 57, 58, 20, 50, 10, 49, 45, 21, 67, 90, 30, 7,  2,  70, 69},
        {78, 35, 94, 59, 8,  23, 10, 76, 96, 80, 93, 9,  27, 95, 61, 84, 88, 91, 2,  33,
         1,  85, 3,  36, 79, 18, 92, 5,  34, 81, 98, 40, 38, 68, 90, 70, 89, 65, 48, 6,
         77, 30, 72, 62, 16, 83, 32, 54, 99, 82, 75, 41, 53, 17, 67, 43, 28, 21, 46, 7,
         25, 64, 13, 14, 87, 58, 63, 31, 39, 47, 24, 71, 74, 55, 20, 11, 22, 45, 44, 51,
         37, 15, 42, 56, 66, 29, 86, 49, 69, 57, 73, 50, 60, 0,  4,  19, 52, 97, 12, 26},
        {88, 86, 41, 1,  70, 10, 19, 2,  11, 44, 87, 26, 53, 59, 40, 18, 61, 13, 21, 56,
         85, 75, 25, 5,  97, 7,  36, 67, 76, 79, 90, 65, 91, 0,  98, 89, 20, 55, 93, 58,
         28, 63, 6,  83, 47, 71, 73, 49, 39, 31, 48, 69, 82, 50, 78, 62, 14, 74, 29, 54,
         57, 80, 32, 94, 3,  66, 30, 35, 8,  46, 16, 51, 24, 17, 4,  84, 45, 60, 34, 15,
         72, 77, 42, 12, 64, 9,  33, 95, 81, 96, 38, 43, 52, 99, 22, 92, 27, 23, 37, 68},
        {90, 93, 83, 21, 96, 71, 67, 28, 37, 75, 55, 58, 56, 39, 16, 46, 91, 41, 77, 92,
         99, 65, 27, 5,  24, 1,  69, 7,  31, 35, 33, 64, 12, 14, 45, 11, 98, 0,  57, 72,
         74, 13, 61, 40, 63, 89, 53, 85, 18, 76, 2,  70, 20, 60, 84, 52, 25, 43, 54, 17,
         36, 19, 97, 73, 94, 62, 3,  23, 34, 88, 29, 80, 50, 22, 81, 87, 6,  30, 78, 48,
         79, 44, 66, 8,  51, 86, 4,  15, 42, 10, 82, 32, 68, 26, 38, 47, 49, 9,  95, 59},
    },
};

static const uint8_t access_code_table_2[10][10] = {
    {4, 7, 8, 0, 9, 1, 3, 6, 2, 5},
    {5, 0, 4, 1, 3, 8, 9, 7, 6, 2},
    {0, 2, 7, 8, 9, 1, 6, 3, 5, 4},
    {5, 9, 8, 4, 1, 7, 0, 2, 3, 6},
    {7, 3, 0, 1, 8, 9, 6, 5, 2, 4},
    {7, 2, 4, 0, 1, 9, 6, 3, 5, 8},
    {4, 1, 6, 3, 5, 8, 0, 7, 2, 9},
    {6, 8, 4, 1, 5, 3, 7, 2, 9, 0},
    {4, 1, 8, 3, 7, 2, 0, 6, 5, 9},
    {7, 4, 5, 6, 2, 3, 9, 1, 8, 0}};

static void rotate_right(uint8_t* data, int n_bytes, int n_bits) {
    uint8_t prior = data[n_bytes - 1];
    for(int i = 0; i < n_bytes; i++) {
        uint8_t tmp = data[i];
        data[i] = (data[i] >> n_bits) | ((prior & ((1 << n_bits) - 1)) << (8 - n_bits));
        prior = tmp;
    }
}

static void decrypt_spad_0(const uint8_t* spad, uint8_t* decrypted) {
    for(int i = 0; i < 16; i++) {
        decrypted[i] = s_box[N_TABLES][spad[i]];
    }

    int count = (decrypted[15] >> 4) + 7;
    int table = decrypted[15] + ITERATION_ADD * count;

    for(int iter = 0; iter < count; iter++) {
        table -= ITERATION_ADD;
        rotate_right(decrypted, 15, 5); // only the first 15 bytes
        for(int i = 0; i < 15; i++) {
            decrypted[i] = s_box[table % N_TABLES][decrypted[i]];
        }
    }
}

static uint16_t crc16(uint64_t data, int bits, uint16_t init, uint16_t poly) {
    uint16_t v = init;
    for(int i = 0; i < bits; ++i) {
        v = (v >> 1) ^ (((v ^ data) & 1ULL) ? poly : 0);
        data >>= 1;
    }
    return v;
}

static bool
    check_access_code_crc(const uint8_t ac[3], const uint8_t body[6], const uint8_t crc[5]) {
    uint64_t msg = 0;
    for(int i = 0; i < 3; ++i) {
        if(ac[i] > 0xF) return false;
        msg = (msg << 4) | ac[i];
    }
    for(int i = 0; i < 6; ++i) {
        uint8_t v = body[i];
        if(v > 99) return false;
        msg = (msg << 4) | (v / 10);
        msg = (msg << 4) | (v % 10);
    }
    uint16_t calculated_crc = crc16(msg, 60, 0xFFFF, 0x8408);
    uint16_t expected_crc = crc[0] * 10000 + crc[1] * 1000 + crc[2] * 100 + crc[3] * 10 + crc[4];
    return (calculated_crc == expected_crc);
}

static void parse_access_code(const uint8_t* access_code, FuriString* parsed_data) {
    furi_assert(access_code);
    furi_assert(parsed_data);

    uint8_t decrypted[6];
    // decrypted contains the decoded serial bytes (as 6 BCD bytes)
    for(int i = 0, j = 3; i < 6; ++i, j += 2) {
        decrypted[i] = (access_code[j]) * 10 + (access_code[j + 1]);
    }

    uint8_t crc[5] = {0};
    memcpy(crc, access_code + 15, 5);

    int boxes1[6] = {
        (crc[3] + crc[2]) % 10, crc[2], crc[3], crc[4], (crc[4] + crc[0]) % 10, crc[1]};

    for(int n = 0; n < 6; ++n) {
        decrypted[n] = access_code_table_1[4][boxes1[n]][decrypted[n]];
    }

    int rv = decrypted[0] / 10;

    int boxes2[6] = {
        (crc[1] + crc[0]) % 10, crc[1], crc[2], crc[3], crc[4], (crc[4] + crc[1]) % 10};
    for(int n = 0; n < 6; ++n) {
        if(n == 0) {
            decrypted[n] = (decrypted[n] & 0xF0) |
                           access_code_table_2[boxes2[n]][decrypted[n] & 0x0F];
        } else {
            decrypted[n] = access_code_table_1[rv][boxes2[n]][decrypted[n]];
        }
    }

    furi_string_cat_printf(
        parsed_data,
        "Decrypted serial number:\n%02d%02d%02d%02d%02d%02d\n",
        decrypted[0],
        decrypted[1],
        decrypted[2],
        decrypted[3],
        decrypted[4],
        decrypted[5]);

    furi_string_cat_printf(
        parsed_data,
        "CRC check: %s\n",
        check_access_code_crc(access_code, decrypted, crc) ? "Passed" : "Invalid");
}

bool aic_parse(const NfcDevice* device, FuriString* parsed_data) {
    furi_assert(device);
    furi_assert(parsed_data);
    bool parsed = false;

    if(nfc_device_get_protocol(device) != NfcProtocolFelica) return false;

    const FelicaData* data = nfc_device_get_data(device, NfcProtocolFelica);

    const uint8_t ic_type = data->pmm.data[1];
    if(ic_type != 0xF0 && ic_type != 0xF1) {
        // Must be Felica Lite (0xF0) or Lite-S (0xF1) to parse
        return false;
    }

    const uint8_t data_format_code_1 = data->data.fs.id.data[8];
    if(data_format_code_1 != 0) {
        // We only know Data Format Code {0x00, 0xXX}
        return false;
    }

    parsed = true;
    furi_string_printf(parsed_data, "\e#Amusement IC Card\n");
    furi_string_cat_str(
        parsed_data, "::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::");
    furi_string_cat_str(parsed_data, "\nType:\n");

    // Determine card brand and type
    const uint8_t data_format_code_2 = data->data.fs.id.data[9];
    switch(data_format_code_2) {
    case 0x2A:
        furi_string_cat_str(parsed_data, "Bandai Namco Passport\n");
        break;
    case 0x3A:
        furi_string_cat_str(parsed_data, "Bandai Namco Passport (Old)\n");
        break;
    case 0x68:
        furi_string_cat_str(parsed_data, "Konami e-amusement pass\n");
        break;
    case 0x78:
        furi_string_cat_str(parsed_data, "SEGA Aime\n");
        break;
    case 0x79:
        furi_string_cat_str(parsed_data, "Taito NESiCA\n");
        break;
    default:
        parsed = false;
        return parsed; // Unknown vendor
    }
    furi_string_cat_str(
        parsed_data, "::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::");

    // decrypt_spad_0 S-PAD 0
    uint8_t decrypted[16] = {0};
    decrypt_spad_0(data->data.fs.spad[0].data, decrypted);

    // Get Access Code
    uint8_t access_code[20] = {0};
    for(int i = 0; i < 10; i++) {
        access_code[i * 2] = (decrypted[i + 6] & 0xF0) >> 4; // Get upper nibble
        access_code[i * 2 + 1] = decrypted[i + 6] & 0x0F; // Get lower nibble
    }
    furi_string_cat_str(parsed_data, "\nAccess Code:\n");
    bool access_code_is_bcd = true;
    for(int i = 0; i < 20; i++) {
        furi_string_cat_printf(parsed_data, "%d", access_code[i]);
        if(i % 4 == 3) {
            furi_string_cat_str(parsed_data, " ");
        }
        if(access_code[i] > 9) access_code_is_bcd = false;
    }
    furi_string_cat_str(parsed_data, "\n");

    furi_string_cat_printf(parsed_data, "BCD valid: %s\n", access_code_is_bcd ? "Yes" : "No");
    furi_string_cat_str(
        parsed_data, "::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::");

    // Parse Access Code
    if(access_code_is_bcd && access_code[0] == 5) {
        furi_string_cat_str(parsed_data, "\n");
        parse_access_code(access_code, parsed_data);
    } else {
        furi_string_cat_printf(
            parsed_data, "\nAccess code preamble wrong: expected 5, got %d\n", access_code[0]);
    }

    furi_string_cat_str(
        parsed_data, "::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::");
    furi_string_cat_str(parsed_data, "\nDecrypted S-PAD 0:\n");
    for(int i = 0; i < 16; i++) {
        furi_string_cat_printf(parsed_data, "%02X ", decrypted[i]);
        if(i == 7) {
            furi_string_cat_str(parsed_data, "\n");
        }
    }
    furi_string_cat_str(parsed_data, "\n");
    furi_string_cat_str(
        parsed_data, "::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::");

    return parsed;
}

/* Actual implementation of app<>plugin interface */
static const NfcSupportedCardsPlugin aic_plugin = {
    .protocol = NfcProtocolFelica,
    .verify = NULL,
    .read = NULL,
    .parse = aic_parse,
};

/* Plugin descriptor to comply with basic plugin specification */
static const FlipperAppPluginDescriptor aic_plugin_descriptor = {
    .appid = NFC_SUPPORTED_CARD_PLUGIN_APP_ID,
    .ep_api_version = NFC_SUPPORTED_CARD_PLUGIN_API_VERSION,
    .entry_point = &aic_plugin,
};

/* Plugin entry point - must return a pointer to const descriptor  */
const FlipperAppPluginDescriptor* aic_plugin_ep(void) {
    return &aic_plugin_descriptor;
}
